今天我們要完成 homePage 的一部分功能,跟 todo 有關的部分,其實鐵人賽也到尾聲了,我要誠實的跟大家說,在鐵人賽的期間確定無法完成這個專案,不過也沒關係,在努力一下。
我寫了 26 篇,卻一直忘記一件事,今天就來跟大家說一下,其實我習慣會把我要做的事情一項一項寫下來,例如這樣 :
// 彈跳視窗
// 加入 list
// 把一個 todo 放到釘選位置
// 思考要釘選哪一種 todo
偷偷推薦一個我自己很喜歡的 vscode 套件 :Comment Anchors,我很常使用它來標記我的段落,也包含我自己接下來想寫的 code。
決定要做的事之後,首先,把 slice 引入進來之後,使用 Selector 來取得 state,中間 :
...
import { useAppSelector, useAppDispatch } from "../redux/hooks";
import {
selectModalIsOpen,
openModal,
closeModal,
} from "../redux/modalSlice/modalSlice";
import { selectList, addTodo } from "../redux/todoSlice/todoSlice";
...
// const [isOpen, setIsOpen] = useState(false);
const isOpen = useAppSelector(selectModalIsOpen);
const list = useAppSelector(selectList);
console.log("list", list, "isOpen", isOpen);
...
新增一個 home 資料夾,HomePage 放進來,把報錯清除,之後就先無腦的把 TodoModal 複製一份變成 HomeModal,相同的 code 靜待下一次重購的時候處理,記得從 homePage 傳入 必要的 props 喔 :
HomeModal.tsx
import React from "react";
import Modal from "../../components/Modal";
type Props = {
isOpen?;
closeModal;
onSubmit;
register;
handleSubmit;
reset;
};
const HomeModal: React.FC<Props> = ({
isOpen,
closeModal,
onSubmit,
register,
handleSubmit,
reset,
}) => {
return (
<Modal isOpen={isOpen}>
<div className="flex justify-end">
<span
className="
font-medium
cursor-pointer
inline-block
bg-gray-200
w-[24px] text-center rounded"
onClick={closeModal}
>
X
</span>
</div>
<div className="py-12 flex flex-col justify-center items-center">
<h2 className="text-2xl font-bold">新增待辦</h2>
<div className="mt-8">
<form onSubmit={handleSubmit(onSubmit)}>
<div className="grid grid-cols-1 gap-[8px] w-[340px]">
<label className="block ">
<span className="text-gray-700">標題</span>
<input
type="text"
className="
mt-1
block
w-full
rounded-md
bg-gray-100
border-transparent
focus:border-gray-500 focus:bg-white focus:ring-0
"
{...register("title", { required: true })}
/>
</label>
<label className="block">
<span className="text-gray-700">時間</span>
<input
type="date"
className="
mt-1
block
w-full
rounded-md
bg-gray-100
border-transparent
focus:border-gray-500 focus:bg-white focus:ring-0
"
{...register("time")}
value="2018-07-22"
/>
</label>
<label className="block">
<span className="text-gray-700">詳情描述</span>
<textarea
className="
mt-1
block
w-full
rounded-md
bg-gray-100
border-transparent
focus:border-gray-500 focus:bg-white focus:ring-0
"
rows={3}
{...register("info")}
/>
</label>
<label className="flex justify-center items-center">
<input
type="submit"
className="
mt-1
block
w-full py-[4px]
cursor-pointer
rounded-md
bg-gray-300
border-transparent
focus:border-gray-500 focus:bg-white focus:ring-0
"
/>
</label>
</div>
</form>
</div>
</div>
</Modal>
);
};
export default HomeModal;
跟 todoPage 一樣,加一下吧~
...
<HomeModal
isOpen={isOpen}
closeModal={() => dispatch(closeModal())}
register={register}
onSubmit={onSubmit}
handleSubmit={handleSubmit}
reset={reset}
/>
...
<AddButton onClick={() => dispatch(openModal())} />
思考許久,我打算用最近一次新增的 todo 當作釘選的目標,所以我們要來把最近一次新增 todo 給揪出來,目前新加入的 todo 都是從後面加,所以就抓最後一個項目,新增一個 state 讓 home 持有 :
...
const [todo, setTodo] = useState(()=>list[list.length - 1]);
...
加上這一步就算完成。
...
<div className="flex flex-col justify-center ml-[8px] px-[8px] w-[800px] pr-[8px]">
<div className="w-full flex">
<div className="w-2/12 flex items-center justify-center bg-gray-200 rounded-l-xl">
已釘選
</div>
<div className="bg-slate-50 w-full pl-[8px]">
<h3 className="">{todo.title}</h3>
<div className="text-sm">{todo.info}</div>
</div>
</div>
</div>
...
最後的 HomePage :
import React from "react";
import { useState } from "react";
import AddButton from "../../features/AddButton";
import HomeModal from "./HomeModal";
import { useAppSelector, useAppDispatch } from "../../redux/hooks";
import {
selectModalIsOpen,
openModal,
closeModal,
} from "../../redux/modalSlice/modalSlice";
import { selectList, addTodo } from "../../redux/todoSlice/todoSlice";
import { useForm } from "react-hook-form";
const HomePage: React.FC = () => {
const dispatch = useAppDispatch();
const isOpen = useAppSelector(selectModalIsOpen);
const list = useAppSelector(selectList);
const [todo, setTodo] = useState(()=>list[list.length - 1]);
const {
register,
handleSubmit,
watch,
reset,
formState: { errors },
} = useForm();
console.log("list", list, "isOpen", isOpen);
const onSubmit = (data) => {
// setList([...list, data]);
dispatch(addTodo(data));
if (isOpen) dispatch(closeModal());
reset();
console.log("list", list);
};
return (
<>
<HomeModal
isOpen={isOpen}
closeModal={() => dispatch(closeModal())}
register={register}
onSubmit={onSubmit}
handleSubmit={handleSubmit}
reset={reset}
/>
<section className="max-w-[1200px] mx-auto my-0 pt-[40px]">
<div className="flex items-center justify-between">
<AddButton onClick={() => dispatch(openModal())} />
<div className="flex flex-col justify-center ml-[8px] px-[8px] w-[800px] pr-[8px]">
<div className="w-full flex">
<div className="w-2/12 flex items-center justify-center bg-gray-200 rounded-l-xl">
已釘選
</div>
<div className="bg-slate-50 w-full pl-[8px]">
<h3 className="">{todo.title}</h3>
<div className="text-sm">{todo.info}</div>
</div>
</div>
</div>
</div>
<div className="pt-[20px]">
<ul className="flex justify-between">
<li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
鐵櫃
</li>
<li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
書櫃
</li>
<li className="p-[8px] mr-[16px] h-[600px] w-[450px] bg-gray-300">
桌子
</li>
<li className="p-[8px] h-[600px] w-[450px] bg-gray-300">冰箱</li>
</ul>
</div>
</section>
</>
);
};
export default HomePage;
今天完成了 todo 釘選的部分,成就感很微妙,堅持到今天了呢,繼續再接再厲。